• Jump To … +
    main.js separate.js single.js web-apg-api.js main.js web-conv-api.js ast.js csv.js dangling-else.js display.js flags.js float.js limits.js main.js multiline-mode.js recursive.js replace.js rules.js split.js testonly.js trace.js udt.js unicode.js web-email.js word-boundaries.js main.js phone-number.js web-main.js web-phone-number.js main.js phone-number.js setup.js translate.js xml.js branch-fail-grammar.js main.js parent-mode-grammar.js setup.js universal-mode-grammar.js colors-app.js colors-callbacks.js colors.js main.js more-app.js more-setup.js more.js ast-callbacks.js bad-input.js basic.js ini-file.js main.js parser-callbacks.js setup.js trace.js anbncn.js and.js c-comment.js compound.js main.js nested.js not.js setup.js boundaries-grammar.js boundaries.js comment-grammar.js comment.js main.js negative-grammar.js negative.js positive-grammar.js positive.js setup.js main.js odata-grammar.js run.js setup.js area-code.js lookaround.js main.js phone-number.js setup.js simple.js all-operators.js default.js fancy-number.js limited-lines.js main.js select-operators.js select-rules.js setup.js main.js minimal.js parent-u.js parent.js phone-number.js setup.js stats.js trace.js universal-u.js universal.js callbacks.js grammar.js main.js parser.js writeHtml.js LICENSE.md README.md index.md
  • flags.js

  • §
    /*  *************************************************************************************
     *   copyright: Copyright (c) 2021 Lowell D. Thomas, all rights reserved
     *     license: BSD-2-Clause (https://opensource.org/licenses/BSD-2-Clause)
     *   ********************************************************************************* */
  • §

    This module briefly describes all of the arguments to the apg-exp constructor and demonstrates in detail the four different flags available.

    let ApgExp = require("apg-exp");
    let exp = new ApgExp(grammar, flags, nodeHits, treeDepth);
    grammar   - this can be either a string defining the
                SABNF grammar or a pre-compiled grammar object.
              - e.g. grammar = 'rule = "a" / "b"\n';
                (note: newline character is required
                 by the SABNF syntax)
              - or grammar = new (require("/path/to/rule.js")();
                where rule.js was previously created
                with the apg parser generator.
    flags     - any combination of g, y, u and d.
                (note: if both g and y are specified,
                y prevails)
    nodeHits  - limits the number of node hits (unit parser steps)
    treeDepth - limits the maximum depth allowed of the parse tree
    

    The flags available to the exec() function are described in more detail below. (All flags are ignored by the test() function.)

    • `g` - the `global` flag is used to match all occurrences of a pattern in a string. This is used with repeated calls to the `exec()` function. After each successful pattern match, the `lastIndex` variable is repositioned to the character just following the match. After an unsuccessful match, `lastIndex` is reset to zero. When used with the `replace()` function, all occurrences of the pattern are replaced with one call.
    • `y` - the `sticky` flag is described in the MDN) documentation, but does not seem to be implemented in `node.js`. With the `y` flag set, `lastIndex` acts as an anchor. The match is attempted at the index `lastIndex` only. If a match is not found, `lastIndex` is set to 0 and the result is null. If a match is found, it acts similarly to global mode in that `lastIndex` is repositioned to the next character following the match. Therefore, it can also be used with repeated calls to `exec()`, finding all *consecutive* phrases that exactly follow one another. When used with the `replace()` function, all consecutive occurrences of the pattern are replaced with one call.
    • `u` - with the unicode flag set, all matched phrases in the `result` and `last match` objects are returned as arrays of character code integers rather than JavaScript strings. (The `replace()` and `split()` functions will throw an exception if called with the `u` flag set.)
    • `d` - the debug flag is used to turn on tracing, `apg`'s debugger. The `apg` tracing object can be configured and displayed just as with any other `apg` application to see exactly how the parser is behaving.

    Some simple examples of using each of these flags follow.

    (function flagsEsample() {
      try {
        const apgJs = require('apg-js');
    
        const ApgExp = apgJs.apgExp;
        const grammar = 'rule = "abc" / "xyz"\n';
        let exp;
        let flags;
        let result;
        let str;
  • §

    With no flags, lastIndex remains at 0 after a successful match and repeated calls simply find the same match.

        console.log();
        console.log('The flags demonstration');
        console.log();
        console.log(`  grammar: ${grammar}`);
        flags = '';
        exp = new ApgExp(grammar, flags);
        str = '---abc---xyz---ABC---';
        result = exp.exec(str);
        console.log('         : With no flags, lastIndex is never repositioned. The same phrase is found over and over.');
        console.log(`    flags: '${exp.flags}'`);
        console.log(`    input: '${str}'`);
        console.log(`lastIndex: ${exp.lastIndex}: index: ${result.index}: result[0]: '${result[0]}'`);
        result = exp.exec(str);
        console.log(`lastIndex: ${exp.lastIndex}: index: ${result.index}: result[0]: '${result[0]}'`);
        result = exp.exec(str);
        console.log(`lastIndex: ${exp.lastIndex}: index: ${result.index}: result[0]: '${result[0]}'`);
  • §

    With the global flag, g, repeated calls will find the next match.

        flags = 'g';
        exp = new ApgExp(grammar, flags);
        console.log();
        console.log("         : With the 'g' flag, lastIndex is repositioned. Each call finds the next phrase.");
        console.log(`    flags: '${exp.flags}'`);
        console.log(`    input: '${str}'`);
        const TRUE = true;
        while (TRUE) {
          result = exp.exec(str);
          if (result === null || result[0] === '') {
            console.log(`lastIndex: ${exp.lastIndex}: result: '${result}'`);
            break;
          }
          console.log(`lastIndex: ${exp.lastIndex}: index: ${result.index}: result[0]: '${result[0]}'`);
        }
  • §

    With the ‘sticky’ flag, y, the patterns must be consecutive for repeated matching.

        flags = 'y';
        exp = new ApgExp(grammar, flags);
        console.log();
        console.log("         : With the 'y' flag, lastIndex is an anchor. The phrase must be found exactly at lastIndex.");
        console.log(`    flags: '${exp.flags}'`);
        console.log(`    input: '${str}'`);
        while (TRUE) {
          result = exp.exec(str);
          if (result === null || result[0] === '') {
            console.log(`lastIndex: ${exp.lastIndex}: result: '${result}'`);
            break;
          }
          console.log(`lastIndex: ${exp.lastIndex}: index: ${result.index}: result[0]: '${result[0]}'`);
        }
        str = 'abcxyzABC';
        console.log();
        console.log("         : With the 'y' flag, 'consecutive' phrases will be found with subsequent calls.");
        console.log(`    flags: '${exp.flags}'`);
        console.log(`    input: '${str}'`);
        while (TRUE) {
          result = exp.exec(str);
          if (result === null || result[0] === '') {
            console.log(`lastIndex: ${exp.lastIndex}: result: '${result}'`);
            break;
          }
          console.log(`lastIndex: ${exp.lastIndex}: index: ${result.index}: result[0]: '${result[0]}'`);
        }
  • §

    With the unicode flag, u, the result is an array of character codes rather than a string.

        flags = 'ug';
        exp = new ApgExp(grammar, flags);
        str = '---abc---xyz---ABC---';
        console.log();
        console.log("         : With the 'u' flag, phrases are arrays of character codes, not strings.");
        console.log(`    flags: '${exp.flags}'`);
        console.log(`    input: '${str}'`);
        while (TRUE) {
          result = exp.exec(str);
          if (result === null || result[0] === '') {
            console.log(`lastIndex: ${exp.lastIndex}: result: '${result}'`);
            break;
          }
          console.log(`lastIndex: ${exp.lastIndex}: index: ${result.index}: result[0]: '[${result[0]}]'`);
        }
  • §

    With the debug flag, d, the trace object is available for inspection. We will see in other examples how to configure and display the trace information. For now, we just demonstrate that the trace object can be made available with the d flag.

        flags = 'd';
        exp = new ApgExp(grammar, flags);
        console.log();
        console.log("         : When the 'd' flag is set, the exp.trace object is available for use.");
        console.log(`    flags: '${exp.flags}'`);
        console.log(`exp.trace: ${exp.trace}`);
        flags = '';
        exp = new ApgExp(grammar, flags);
        console.log();
        console.log("         : When the 'd' flag is not set, the exp.trace object is null.");
        console.log(`    flags: '${exp.flags}'`);
        console.log(`exp.trace: ${exp.trace}`);
      } catch (e) {
        console.log(`EXCEPTION: ${e.message}`);
      }
    })();